#include <stdio.h>

// 转移表
// 本质上,就是利用函数指针进行对函数的灵活调用,避免了许多重复的代码块
// 下面就是最最经典的: 计算器,计算机专业学生人手一块
// 因为计算机可以有几种复现方式: 选择结构,顺序表
// 从结构上来说,明显顺序表更好,因为顺序表可以省略选择结构很多重复性的代码

int add (int x , int y) { return x + y ; } // 函数1: 返回相加值

int dim (int x , int y) { return x - y ; } // 函数2: 返回相减值

int mul (int x , int y) { return x * y ; }  // 函数3: 返回相乘值

int div (int x , int y) { return x / y ; } // 函数4: 返回相除值

void cmp (int (*fun) (int , int))
{

    int x , y ;

    printf ("\n请输入想运算的两个数字: ") ;

    scanf ("%d %d" , &x , &y) ;

    int number = fun (x , y) ;

    printf ("\n得数为: %d\n" , number) ;
    
}

void menu ()
{

    printf ("----------\n") ;
    printf ("- 计算器  -\n") ;
    printf ("- 1.加法  -\n") ;
    printf ("- 2.减法  -\n") ;
    printf ("- 3.乘法 -\n") ;
    printf ("- 4.除法 -\n") ;
    printf ("----------\n") ;

}

int main ()
{

    int input = 0 ;

    int (*table [5]) (int , int) = { 0 , add , dim , mul , div } ; // 这里可以看到,我们创建了一个函数指针数组,用来存放四个函数的地址,这样我们就可以通过对数组元素的解引用来实现访问函数的效果

    do
    {

        menu () ;

        printf ("请选择功能: ") ;

        scanf ("%d" , &input) ;

        if (0 < input && input < 5)
        {

            cmp (table [input]) ; // table [input] == *(table + input) 根据input的数字来实现访问特定的函数

        }

        else if (input == 0)
        {

            printf ("\n退出计算机。") ;

        }

        else
        {

            printf ("选择错误,请重新选择!\n") ;

        }

    }while (input) ;

    return 0 ;

}